<script lang="ts" setup>
import type { SystemDeptApi } from '#/api/system/dept';
import type { SystemRoleApi } from '#/api/system/role';

import { computed, defineProps, ref, watch } from 'vue';

import { Tree } from '@vben/common-ui';
import { SystemDataScopeEnum } from '@vben/constants';
import { handleTree } from '@vben/utils';

import { Checkbox, message } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { getDeptList } from '#/api/system/dept';
import { assignRoleDataScope } from '#/api/system/permission';
import { getRole } from '#/api/system/role';
import { $t } from '#/locales';

import { useAssignDataPermissionFormSchema } from '../data';

const props = defineProps({
  role: {
    type: Object as () => SystemRoleApi.Role,
    default: null,
  },
});

const emit = defineEmits(['success']);

const deptTree = ref<SystemDeptApi.Dept[]>([]); // 部门树
const deptLoading = ref(false); // 加载部门列表
const isAllSelected = ref(false); // 全选状态
const isExpanded = ref(false); // 展开状态
const isCheckStrictly = ref(true); // 父子联动状态
const expandedKeys = ref<number[]>([]);

// 表单和表单API
const [Form, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-2',
    labelWidth: 80,
  },
  layout: 'horizontal',
  schema: useAssignDataPermissionFormSchema(
    computed(() => props.role.editable),
    computed(() => props.role.userDataScope),
  ),
  showDefaultActions: false,
});

// 监听角色变化并初始化
watch(
  () => props.role?.id,
  async (roleId) => {
    if (roleId) {
      await init(roleId);
    }
  },
  { immediate: true },
);

// 初始化数据
async function init(roleId: number) {
  try {
    resetState();
    const roleDetail = await getRole(roleId);
    await loadDeptTree();
    toggleExpandAll();
    // 设置表单值, 一定要在加载树之后
    await formApi.setValues(roleDetail);
  } catch (error) {
    console.error(error);
  }
}

// 加载部门树
async function loadDeptTree() {
  deptLoading.value = true;
  try {
    const data = await getDeptList();
    deptTree.value = handleTree(data) as SystemDeptApi.Dept[];
  } finally {
    deptLoading.value = false;
  }
}

// 表单提交保存
async function handleSubmit() {
  const { valid } = await formApi.validate();
  if (!valid) return;

  const data = await formApi.getValues();
  try {
    await assignRoleDataScope({
      roleId: data.id,
      dataScope: data.dataScope,
      dataScopeDeptIds:
        data.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
          ? data.dataScopeDeptIds
          : undefined,
    });
    emit('success');
    message.success($t('ui.actionMessage.operationSuccess'));
  } catch (error) {
    console.error(error);
  }
}

// 全选/全不选
function toggleSelectAll() {
  isAllSelected.value = !isAllSelected.value;
  const allIds = isAllSelected.value ? getAllNodeIds(deptTree.value) : [];
  formApi.setFieldValue('dataScopeDeptIds', allIds);
}

// 展开/折叠所有节点
function toggleExpandAll() {
  isExpanded.value = !isExpanded.value;
  expandedKeys.value = isExpanded.value ? getAllNodeIds(deptTree.value) : [];
}

// 切换父子联动
function toggleCheckStrictly() {
  isCheckStrictly.value = !isCheckStrictly.value;
}

// 重置状态
function resetState() {
  isAllSelected.value = false;
  isExpanded.value = false;
  isCheckStrictly.value = true;
  expandedKeys.value = [];
  deptTree.value = [];
}

// 递归获取所有节点 ID
function getAllNodeIds(nodes: any[], ids: number[] = []): number[] {
  nodes.forEach((node: any) => {
    ids.push(node.id);
    if (node.children?.length) {
      getAllNodeIds(node.children, ids);
    }
  });
  return ids;
}
function changeExpand(item: any, isExpanded: boolean) {
  console.log(item);
  if (isExpanded) {
    expandedKeys.value = expandedKeys.value.filter(
      (id) => id !== item.value.id,
    );
  } else {
    expandedKeys.value.push(item.value.id);
  }
}
</script>

<template>
  <div class="mb-4 flex items-center justify-between">
    <h2 class="text-lg font-semibold">数据权限</h2>
    <a-button
      :disabled="!props.role.editable"
      type="primary"
      @click="handleSubmit"
    >
      保存
    </a-button>
  </div>

  <Form class="mx-4">
    <template #dataScopeDeptIds="slotProps">
      <div class="w-full">
        <div class="mb-2 flex items-center space-x-4">
          <Checkbox
            :checked="isAllSelected"
            @change="toggleSelectAll"
            :disabled="!props.role.editable"
          >
            全选
          </Checkbox>
          <Checkbox :checked="isExpanded" @change="toggleExpandAll">
            全部展开
          </Checkbox>
          <Checkbox
            :checked="isCheckStrictly"
            @change="toggleCheckStrictly"
            :disabled="!props.role.editable"
          >
            父子联动
          </Checkbox>
        </div>

        <div class="w-full">
          <Tree
            :tree-data="deptTree"
            multiple
            bordered
            :spinning="deptLoading"
            :expanded="expandedKeys"
            @expand="changeExpand"
            v-bind="slotProps"
            value-field="id"
            label-field="name"
            :auto-check-parent="false"
            :check-strictly="!isCheckStrictly"
            :disabled="!props.role.editable"
          />
        </div>
      </div>
    </template>
  </Form>
</template>
